package com.agent.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.agent.entity.Dept;
import com.agent.entity.Dict;
import com.agent.entity.RepaireInfo;
import com.agent.entity.User;
import com.agent.page.EasyuiPage;
import com.agent.repository.DictMapper;
import com.agent.repository.RepaireInfoMapper;
import com.agent.repository.UserMapper;
import com.agent.service.IDeptService;
import com.agent.service.IDictService;
import com.agent.service.IRepaireInfoService;
import com.agent.service.UserService;
import com.agent.util.Constants;
import com.agent.vo.RepaireInfoVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.weixin.pojo.Textcard;
import com.weixin.pojo.WXMsg;
import com.weixin.pojo.WXUser;
import com.weixin.service.WeixinNotifyService;
import com.weixin.util.WXUserUtil;
import com.weixin.util.WXUtil;
import com.weixin.util.WxepConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;


@Service("repaireInfoService")
@Slf4j
public class RepaireInfoServiceImpl implements IRepaireInfoService {

    @Autowired
    protected RepaireInfoMapper repaireInfoMapper;

    @Resource(name = "allocationService")
    AllocationService allocationService;

    @Resource(name = "dictService")
    IDictService dictService;
    @Autowired
    DictMapper dictMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    IDeptService deptService;

    @Resource(name = "userServiceImpl")
    UserService userService;

    @Resource(name = "weixinNotifyService")
    WeixinNotifyService weixinNotifyService;

    public void delete(String id) {
        repaireInfoMapper.delete(id);

    }

    public Long insertAndAllocation(String userId, RepaireInfoVO repaireInfoVO) throws Exception {
        User user = null;
        // 通过扫一扫进来的 直接进入到待接单状态
        if(!StringUtils.isEmpty(repaireInfoVO.getCurrentId())){
            Map<String,String> inParam = new HashMap<String,String>();
            inParam.put("userName",repaireInfoVO.getCurrentId());
            List<User> userList = userMapper.findOne(inParam);
            if(!CollectionUtils.isEmpty(userList)){
                user = userList.get(0);
            }
        }else{
            Dict dict = new Dict();
            dict.setCode(Constants.SYSTEM_MODEL);
            List<Dict> dicts = dictMapper.searchDict(dict);
            if (dicts != null && dicts.size() > 0) {
                String value = dicts.get(0).getDictValue(); // 0:抢单模式  1:自动派单模式
                if ("1".equals(value)) {
                    user = allocationService.allocationUser(0, repaireInfoVO.getAddress());
                }
            }
        }
        RepaireInfo repaireInfo = assemblyInfo(userId,repaireInfoVO,user);
        repaireInfoMapper.insertSelective(repaireInfo);
//        notifyEngineer(user);

        return repaireInfo.getId();

    }

    public User circulation(String userId, RepaireInfoVO repaireInfoVO,String type) throws Exception {
        User in = new User();
        in.setRoleId(3);
        in.setRankId("1"); // 属于组
//        in.setNotNullrankId("true");
        in.setEnabled(true);
        List<User> userList = userMapper.list(in);
        /*List<User> notifyUsers = new ArrayList<>();
        Dict dict = new Dict();
        dict.setCode(Constants.SYSTEM_MODEL);
        List<Dict> dicts = dictMapper.searchDict(dict);
        User user = null;
        if (dicts != null && dicts.size() > 0) {
            String value = dicts.get(0).getDictValue(); // 0:抢单模式  1:自动派单模式
            if ("1".equals(value)) {
                user = allocationService.allocationUser(0, repaireInfoVO.getAddress());
            }
        }
        if(user != null){
            repaireInfoVO.setStatus("06");
            repaireInfoVO.setCurrentId(user.getUserName());
            repaireInfoVO.setCurrentName(user.getDisplayName());
            repaireInfoMapper.update(repaireInfoVO);
            notifyUsers.add(user);
        }*/
        notifyEngineer(userList);
        return null;

    }

    /**
     * 新增工单  进入到待调配状态 01, 扫一扫则直接分配
     * @param userId
     * @param repaireInfoVO
     * @return
     * @throws Exception
     */
    @Override
    public void insertByUserId(String userId, RepaireInfoVO repaireInfoVO) throws Exception {
        add(userId, repaireInfoVO);
    }

    private void add(String userId, RepaireInfoVO repaireInfoVO)throws Exception{
        User user = null;
        // 扫一扫进来的 直接分配个对应工程师
        if(!StringUtils.isEmpty(repaireInfoVO.getCurrentId())){
            User inParam = new User();
            inParam.setUserName(repaireInfoVO.getCurrentId());
            inParam.setRoleId(3);
            inParam.setEnabled(true);
            List<User> userList = userMapper.list(inParam);
            if(!CollectionUtils.isEmpty(userList)){
                user = userList.get(0);
            }
        }
        RepaireInfo repaireInfo = assemblyInfo(userId,repaireInfoVO,user);
        repaireInfoMapper.insertSelective(repaireInfo);
        if(user !=null){
            List<User> list = new ArrayList<>();
            list.add(user);
            notifyEngineer(list);
        }
    }

    @Override
    public int selectExpaireInfo() throws Exception {
        return repaireInfoMapper.selectExpaireInfo();
    }

    @Override
    public List<RepaireInfo> selectExpaireInfos() throws Exception {
        return repaireInfoMapper.selectExpaireInfos();
    }

    private RepaireInfo assemblyInfo(String userId, RepaireInfoVO repaireInfoVO,User user) throws Exception {
        WXUser wxUser = WXUserUtil.getUser(null, userId);
        RepaireInfo info = new RepaireInfo();
        BeanUtils.copyProperties(repaireInfoVO,info);
        info.setCreateTime(new Date());
        info.setWorkOrderId(WXUtil.gengertorId());
        info.setCreatorPhone(wxUser.getTelephone());
        info.setCreateMobile(wxUser.getMobile());
        info.setCreatorName(wxUser.getName());
        info.setCallerCompanyName(wxUser.getCorpName());
        info.setCallerDeptId(wxUser.getDepartment().replace("[","").replace("]",""));
        if(user != null){
            info.setCurrentId(user.getUserName());
            info.setCurrentName(user.getDisplayName());
            info.setStatus("06");
        }else {
            info.setStatus("01"); // 未找到对应的工程师 则为待调配
        }
        return info;
    }

    @Override
    @Transactional
    public int updateByWorkOrderId(RepaireInfo repaireInfo) {
        return repaireInfoMapper.updateByWorkOrderId(repaireInfo);
    }


    @Transactional(readOnly = true)
    public List<RepaireInfo> getRepaireInfoList(RepaireInfoVO vo) {
        return repaireInfoMapper.searchRepaireInfo(vo);
    }

    @Override
    public List<RepaireInfo> searchRepaireInfoByStatus(Map<String, String> map) {
        List<RepaireInfo> repaireInfoList = repaireInfoMapper.searchRepaireInfoByStatus(map);
        List<Dept> deptList = deptService.listNoPage(new Dept());
        repaireInfoList.forEach(info ->{
            info.setCallerDeptName(coverToName(info.getCallerDeptId(), deptList));
            info.setStatus(Constants.getStatus(info.getStatus()));
            if(StringUtils.isEmpty(info.getFloor())){
                info.setAddress(Constants.getAddress(info.getAddress()));
            }else{
                if("04".equals(info.getAddress())){  // 其他 地区 不添加楼
                    info.setAddress(Constants.getAddress(info.getAddress()) +"-"+info.getFloor());
                }else{
                    info.setAddress(Constants.getAddress(info.getAddress()) +"-"+info.getFloor()+"楼");
                }
            }
        });
        return repaireInfoList;
    }

    @Override
    public List<RepaireInfo> searchRepaireInfoByStatus06(Map<String, String> map) {
        List<RepaireInfo> repaireInfoList = repaireInfoMapper.searchRepaireInfoByStatus06(map);
        List<Dept> deptList = deptService.listNoPage(new Dept());
        repaireInfoList.forEach(info ->{
            info.setCallerDeptName(coverToName(info.getCallerDeptId(), deptList));
            info.setStatus(Constants.getStatus(info.getStatus()));
            if(StringUtils.isEmpty(info.getFloor())){
                info.setAddress(Constants.getAddress(info.getAddress()));
            }else{
                if("04".equals(info.getAddress())){  // 其他 地区 不添加楼
                    info.setAddress(Constants.getAddress(info.getAddress()) +"-"+info.getFloor());
                }else{
                    info.setAddress(Constants.getAddress(info.getAddress()) +"-"+info.getFloor()+"楼");
                }
            }
        });
        return repaireInfoList;
    }

    @Override
    public List<RepaireInfo> searchRepaireInfoPending(Map<String, String> map) {
        List<RepaireInfo> repaireInfoList = repaireInfoMapper.searchRepaireInfoPending(map);
        List<Dept> deptList = deptService.listNoPage(new Dept());
        repaireInfoList.forEach(info ->{
            info.setCallerDeptName(coverToName(info.getCallerDeptId(), deptList));
            info.setStatus(Constants.getStatus(info.getStatus()));
            if(StringUtils.isEmpty(info.getFloor())){
                info.setAddress(Constants.getAddress(info.getAddress()));
            }else{
                if("04".equals(info.getAddress())){  // 其他 地区 不添加楼
                    info.setAddress(Constants.getAddress(info.getAddress()) +"-"+info.getFloor());
                }else{
                    info.setAddress(Constants.getAddress(info.getAddress()) +"-"+info.getFloor()+"楼");
                }
            }
        });
        return repaireInfoList;
    }
    @Override
    public List<RepaireInfo> searchRepaireInfoForCustom(Map<String, String> map) {
        return repaireInfoMapper.searchRepaireInfoByStatus(map);
    }

    public RepaireInfo getRepaireInfo(String id) {
        List<RepaireInfo> list = repaireInfoMapper.getRepaireInfo(id);
        return list == null || list.size() == 0l ? null : list.get(0);
    }
    public RepaireInfo getRepaireInfoByOrderId(String id) {
        List<RepaireInfo> list = repaireInfoMapper.getRepaireInfoByOrderId(id);
        return list == null || list.size() == 0l ? null : list.get(0);
    }

    public void insert(RepaireInfo repaireInfo) throws Exception {
        repaireInfoMapper.insertSelective(repaireInfo);
    }

    public List<RepaireInfo> searchAll() {
        return repaireInfoMapper.searchAll();
    }

    public Workbook exportExcel(RepaireInfoVO vo)throws Exception{
        List<Dept> deptList = deptService.listNoPage(new Dept());
        List<RepaireInfo> list = repaireInfoMapper.searchRepaireInfoForWeb(vo);
        list.forEach(repaireInfo1 -> {
            repaireInfo1.setCallerDeptName(coverToName(repaireInfo1.getCallerDeptId(), deptList));
            if(StringUtils.isEmpty(repaireInfo1.getFloor())){
                repaireInfo1.setAddress(Constants.getAddress(repaireInfo1.getAddress()));
            }else{
                if("04".equals(repaireInfo1.getAddress())){  // 其他 地区 不添加楼
                    repaireInfo1.setAddress(Constants.getAddress(repaireInfo1.getAddress()) +"-"+repaireInfo1.getFloor());
                }else{
                    repaireInfo1.setAddress(Constants.getAddress(repaireInfo1.getAddress()) +"-"+repaireInfo1.getFloor()+"楼");
                }
            }
            repaireInfo1.setExceptionReason(Constants.getExceptionReason(repaireInfo1.getExceptionReason()));
            repaireInfo1.setStatus(Constants.getStatus(repaireInfo1.getStatus()));
            repaireInfo1.setMachineType(Constants.getMachineType(repaireInfo1.getMachineType()));
        });
        return ExcelExportUtil.exportExcel(new ExportParams("工单信息", "工单"),RepaireInfo.class,list);
    }

    @Override
    public EasyuiPage<RepaireInfo> searchRepaireInfo(Integer page, Integer rows, RepaireInfoVO vo) {
        List<Dept> deptList = deptService.listNoPage(new Dept());
        if(!StringUtils.isEmpty(vo.getEmail())){
            List<User> users = userMapper.findByEmail(vo.getEmail());
            if(!CollectionUtils.isEmpty(users)){
                vo.setCreatorPhone(users.get(0).getTelphone());
            }
        }
        PageHelper.startPage(page, rows, true, true, true);
        List<RepaireInfo> list = repaireInfoMapper.searchRepaireInfoForWeb(vo);
        list.forEach(repaireInfo1 -> {
            repaireInfo1.setCallerDeptName(coverToName(repaireInfo1.getCallerDeptId(), deptList));
            if(StringUtils.isEmpty(repaireInfo1.getFloor())){
                repaireInfo1.setAddress(Constants.getAddress(repaireInfo1.getAddress()));
            }else{
                if("04".equals(repaireInfo1.getAddress())){  // 其他 地区 不添加楼
                    repaireInfo1.setAddress(Constants.getAddress(repaireInfo1.getAddress()) +"-"+repaireInfo1.getFloor());
                }else{
                    repaireInfo1.setAddress(Constants.getAddress(repaireInfo1.getAddress()) +"-"+repaireInfo1.getFloor()+"楼");
                }
            }
            repaireInfo1.setMachineType(Constants.getMachineType(repaireInfo1.getMachineType()));
            repaireInfo1.setSource(Constants.getSourceMap(repaireInfo1.getSource()));
        });
        EasyuiPage<RepaireInfo> pages = new EasyuiPage<RepaireInfo>();
        pages.setRows(list);
        PageInfo<RepaireInfo> pageinfo = new PageInfo<RepaireInfo>(list);
        pages.setTotal(pageinfo.getTotal());
        return pages;
    }

    @Override
    public EasyuiPage<RepaireInfo> searchRepaireInfoForReport(Integer page, Integer rows, RepaireInfoVO vo) {
        List<Dept> deptList = deptService.listNoPage(new Dept());
        if(!StringUtils.isEmpty(vo.getEmail())){
            List<User> users = userMapper.findByEmail(vo.getEmail());
            if(!CollectionUtils.isEmpty(users)){
                vo.setCreatorPhone(users.get(0).getTelphone());
            }
        }
        PageHelper.startPage(page, rows, true, true, true);
        List<RepaireInfo> list = repaireInfoMapper.searchRepaireInfo(vo);
        list.forEach(repaireInfo1 -> {
            repaireInfo1.setCallerDeptName(coverToName(repaireInfo1.getCallerDeptId(), deptList));
            if(StringUtils.isEmpty(repaireInfo1.getFloor())){
                repaireInfo1.setAddress(Constants.getAddress(repaireInfo1.getAddress()));
            }else{
                if("04".equals(repaireInfo1.getAddress())){  // 其他 地区 不添加楼
                    repaireInfo1.setAddress(Constants.getAddress(repaireInfo1.getAddress()) +"-"+repaireInfo1.getFloor());
                }else{
                    repaireInfo1.setAddress(Constants.getAddress(repaireInfo1.getAddress()) +"-"+repaireInfo1.getFloor()+"楼");
                }
            }
            repaireInfo1.setMachineType(Constants.getMachineType(repaireInfo1.getMachineType()));
        });
        EasyuiPage<RepaireInfo> pages = new EasyuiPage<RepaireInfo>();
        pages.setRows(list);
        PageInfo<RepaireInfo> pageinfo = new PageInfo<RepaireInfo>(list);
        pages.setTotal(pageinfo.getTotal());
        return pages;
    }

    public static String coverToName(String deptId, List<Dept> deptList) {
        final String[] deptName = {""};
        deptList.forEach(dept -> {
            if (deptId != null && deptId.equals(dept.getQywxId())) {
                deptName[0] = dept.getDeptName();
                return;
            }
        });
        return deptName[0];
    }

    @Transactional
    public synchronized void update(RepaireInfo RepaireInfo) {
        repaireInfoMapper.update(RepaireInfo);
    }

    public RepaireInfoMapper getRepaireInfoMapper() {
        return repaireInfoMapper;
    }

    public void setRepaireInfoMapper(RepaireInfoMapper RepaireInfoMapper) {
        this.repaireInfoMapper = RepaireInfoMapper;
    }

    /**
     * 提醒工程师接单
     * @param list   通知的工程师集合
     * @throws Exception
     */
    public void notifyEngineer(List<User> list) throws Exception {
        //  工程师微信端提醒
        WXMsg wxMsg = new WXMsg();
        wxMsg.setAgentid(WxepConstants.ENGINEER_AGENT_ID);
        wxMsg.setMsgtype("textcard");
        if(!CollectionUtils.isEmpty(list)){
            StringBuffer sb = new StringBuffer();
            for(User u:list){
                sb.append(u.getUserName());
                sb.append("|");
            }
            String toUser = sb.substring(0,sb.length()-1);
            wxMsg.setTouser(toUser);
        }
        Textcard textcard = new Textcard();
        textcard.setTitle("任务来了");
        Dict dict = dictService.getDict(Constants.ENGINEER_NOTIFY);
        textcard.setDescription(dict.getDictValue());
        textcard.setUrl(WxepConstants.ENGINEER_MODIFY_URL);
        wxMsg.setTextcard(textcard);
        weixinNotifyService.sendMsg(wxMsg,WxepConstants.ENGINEER_SECRET);
    }

}
